package com.gitee.minimalismstyle.fresh.common.data.beetl.custom

import org.beetl.sql.annotation.entity.AssignID
import org.beetl.sql.annotation.entity.AutoID
import org.beetl.sql.annotation.entity.SeqID
import org.beetl.sql.clazz.ClassAnnotation
import org.beetl.sql.clazz.ClassDesc
import org.beetl.sql.clazz.NameConversion
import org.beetl.sql.clazz.TableDesc
import org.beetl.sql.clazz.kit.BeanKit
import org.beetl.sql.clazz.kit.CaseInsensitiveHashMap
import java.beans.PropertyDescriptor
import java.lang.reflect.Field

class FreshClassDesc(c: Class<*>, table: TableDesc, nc: NameConversion): ClassDesc(c, table, nc) {
    init {
        targetClass = c
        ca = ClassAnnotation.getClassAnnotation(c)
        val ps = ca.getPropertyDescriptor(c)

        val ids = table.idNames
        val tempMap = CaseInsensitiveHashMap<String, PropertyDescriptor>()

        for (p in ps) {
            //所有属性必须有getter和setter
            if (p.readMethod != null && BeanKit.getWriteMethod(p, c) != null) {
                val property = p.name
                val col = nc.getColName(c, property)
                if (col != null) {
                    tempMap[col] = p
                }
            }
        }


        //取交集

        val idFields: MutableList<Field> = mutableListOf()
        setIdFields(c, idFields)
        //取交集
        for (col in table.cols) {
            if (tempMap.containsKey(col)) {
                cols.add(col)
                val p = tempMap[col] as PropertyDescriptor
                properties.add(p.name)
                val readMethod = p.readMethod
                val retType = readMethod.returnType
                if (idFields.any{it.name == p.name} || ids.contains(col)) {
                    //保持同一个顺序
                    table.addIdName(col)
                    idProperties.add(p.name)
                    idCols.add(col)
                    idMethods[p.name] = readMethod
                }
            }
        }
    }

    private fun setIdFields(clazz: Class<*>, idFields: MutableList<Field>) {
        if(clazz != Any::class.java){
            clazz.declaredFields.forEach {
                if(it.isAnnotationPresent(AssignID::class.java)
                        ||  it.isAnnotationPresent(AutoID::class.java)
                        ||  it.isAnnotationPresent(SeqID::class.java)
                ){
                    val isExist = idFields.any { idField -> idField.name == it.name }
                    if(!isExist){
                        idFields.add(it)
                    }

                }
            }
            setIdFields(clazz.superclass, idFields)
        }
    }
}